/*---------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------*/
// x11peg.hpp - X11 development platform port of PEG.
//
// Author: Jim DeLisle
//
// Copyright (c) 1997-2007 Swell Software, Inc.
//              All Rights Reserved.
//
// Unauthorized redistribution of this source code, in whole or part,
// without the express written permission of Swell Software, Inc.
// is strictly prohibited.
//
/*---------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------*/

#ifndef X11PEG_HPP_
#define X11PEG_HPP_

/*---------------------------------------------------------------------------*/
// Defines for PEG task, message pool and message queue types. If
// we're not running in multithread mode, we use the stand alone
// message queue.
/*---------------------------------------------------------------------------*/
#if defined(PEG_MULTITHREAD)
#define PEG_TASK_TYPE        pthread_t
#define PEG_MUTEX_TYPE       pthread_mutex_t

struct PegMessage;  // forward reference

struct PegX11Pool
{
    PegMessage *pFirst;
    PegMessage *pLast;
};

struct PegX11Queue
{
    PegMessage *pFirst;
    PegMessage *pLast;
    pthread_mutex_t mutex;
    pthread_cond_t cond;
    int count;
};

#define PEG_QUEUE_TYPE      PegX11Queue*
#define PEG_QUEUE_NULL      ((PEG_QUEUE_TYPE) NULL)

#else

#define PEG_QUEUE_TYPE      PegMessageQueue*
#define PEG_QUEUE_NULL      ((PEG_QUEUE_TYPE) NULL)

#endif  // PEG_MULTITHREAD

/*---------------------------------------------------------------------------*/
// Globals
/*---------------------------------------------------------------------------*/
extern Display*         gpDisplay;
extern int              gtScreen;
extern Window           gtDevWin;
extern GC               gtGC;
extern Colormap         gtColormap;
extern int              gnColorDepth;

#if defined(PEG_MULTITHREAD)
extern pthread_t        gtPegMainThread;
extern pthread_mutex_t  gtTimerMutex;
extern pthread_mutex_t  gtQueueMutex;
extern pthread_mutex_t  gtPresentationMutex;
#endif  // PEG_MULTITHREAD

/*---------------------------------------------------------------------------*/
// Prototypes
/*---------------------------------------------------------------------------*/
#if defined(PEG_MULTITHREAD)
void EnterCriticalSection();
void ExitCriticalSection();
void LockMessageQueue();
void UnlockMessageQueue();
void LockTimerList();
void UnlockTimerList();
void LockX11();
void UnlockX11();

PEG_QUEUE_TYPE CreateMsgQueue();
void DeleteMsgQueue(PEG_QUEUE_TYPE tQueue);
void EnqueueTaskMessage(void* pMesg, PEG_QUEUE_TYPE tQueue);
#endif  // PEG_MULTITHREAD

/*---------------------------------------------------------------------------*/
// Multithread defines
/*---------------------------------------------------------------------------*/
#if defined(PEG_MULTITHREAD)
#define LOCK_PEG                    EnterCriticalSection();
#define UNLOCK_PEG                  ExitCriticalSection();
#define LOCK_MESSAGE_QUEUE          LockMessageQueue();
#define UNLOCK_MESSAGE_QUEUE        UnlockMessageQueue();
#define LOCK_TIMER_LIST             LockTimerList();
#define UNLOCK_TIMER_LIST           UnlockTimerList();
#define CURRENT_TASK                pthread_self()
#define PEG_TASK_PTR                gtPegMainThread
#define ENQUEUE_TASK_MESSAGE(a, b)  EnqueueTaskMessage(a, b)
#define LOCK_X11                    LockX11();
#define UNLOCK_X11                  UnlockX11();
#define CREATE_MESG_QUEUE           CreateMsgQueue()
#define DELETE_MESSAGE_QUEUE(a)     DeleteMsgQueue(a)
#else
#define LOCK_PEG
#define UNLOCK_PEG
#define LOCK_MESSAGE_QUEUE
#define UNLOCK_MESSAGE_QUEUE
#define LOCK_TIMER_LIST    
#define UNLOCK_TIMER_LIST
#define CURRENT_TASK 
#define PEG_TASK_PTR
#define ENQUEUE_TASK_MESSAGE(a, b)
#define LOCK_X11
#define UNLOCK_X11
#endif  // PEG_MULTITHREAD

#ifdef PEG_BUILD_PRESS
/*---------------------------------------------------------------------------*/
// Prototypes and defines if we're building the Peg REmote Screen Server
/*---------------------------------------------------------------------------*/
void LockClientList();
void UnlockClientList();
void LockPress();
void UnlockPress();

#define LOCK_CLIENT_LIST            LockClientList();
#define UNLOCK_CLIENT_LIST          UnlockClientList();
#define LOCK_PRESS                  LockPress();
#define UNLOCK_PRESS                UnlockPress();

#endif  // PEG_BUILD_PRESS

#endif    // X11PEG_HPP_

/*---------------------------------------------------------------------------*/
// Lookup table to convert X11 keysym definitions to PEG control keys. The
// regular printable characters don't need to be in here since we don't have
// to translate those into something PEG can use from what X gives us.
/*---------------------------------------------------------------------------*/

#if defined(INCLUDE_KEYSYM_TABLE)

PEGULONG KeySymTable[][2] = {
        { XK_BackSpace,  PK_BACKSPACE },
        { XK_Tab,        PK_TAB       },
        { XK_KP_Tab,     PK_TAB          },
        { XK_Return,     PK_CR        },
        { XK_KP_Enter,   PK_CR          },
        { XK_Escape,     PK_ESC       },
        { XK_Delete,     PK_DELETE    },
        { XK_Insert,     PK_INSERT       },
        { XK_Begin,      PK_HOME      },
        { XK_Home,       PK_HOME      },
        { XK_End,        PK_END       },
        { XK_Prior,      PK_PGUP      },
        { XK_Next,       PK_PGDN      },
        { XK_Up,         PK_LNUP      },
        { XK_Down,       PK_LNDN      },
        { XK_Left,       PK_LEFT      },
        { XK_Right,      PK_RIGHT     },
        { XK_Alt_L,      PK_ALT       },
        { XK_Alt_R,      PK_ALT          },
        { XK_Control_L,  PK_CTRL      },
        { XK_Control_R,  PK_CTRL      },
        { XK_Shift_L,    PK_SHIFT     },
        { XK_Shift_R,    PK_SHIFT      },
        { XK_Caps_Lock,  PK_CAPS      },
        { XK_Shift_Lock, PK_CAPS      },
        { XK_Num_Lock,   PK_NUMLOCK   },
        { XK_F1,         PK_F1        },
        { XK_F2,         PK_F2        },
        { XK_F3,         PK_F3        },
        { XK_F4,         PK_F4        },
        { XK_F5,         PK_F5        },
        { XK_F6,         PK_F6        },
        { XK_F7,         PK_F7        },
        { XK_F8,         PK_F8        },
        { XK_F9,         PK_F9        },
        { XK_F10,        PK_F10       },
        { XK_F11,        PK_F11       },
        { XK_F12,        PK_F12       },
        { 0,             0,           }
    };

#endif // INCLUDE_KEYSYM_TABLE


